<?php
/**
 * Created by PhpStorm.
 * User: User
 * Date: 2017/12/1
 * Time: 14:38
 */

namespace Kinfy\DataBase;


class DB
{
    //数据库PDO连接对象
    public $pdo = null;
    //数据库PDOST对象
    public $pdost = null;
    //要操作的表
    protected $table = '';
    //要查询的字段
    protected $fields = '';
    //待添加的数据或者待更新的数据
    protected $filed_arr = [];
    protected $sql = '';
    //数据库语句类型
    protected $sql_type = '';//INSERT DELETE UPDATE SELECT
    //条数限制
    protected $limit = [0, 0];
    //条件数组的值
    protected $condition_value = [];
    //条件构造完成后的字符串
    protected $condition_str = '';
    //条件连接符
    protected $where_join = '';
    //是否是第一个条件
    protected $is_first_where = true;
    //是否调试输出
    protected $is_debug = false;
    //排序
    protected $order = '';


    public function __construct($dsn = '', $db = '', $user = '', $pass = '')
    {
        $db = $db ?: 'kinfy';
        $dsn = $dsn ?: "mysql:host=127.0.0.1;dbname={$db}";
        $user = $user ?: 'root';
        $pass = $pass ?: 'root';
        try {
            $this->pdo = new \PDO($dsn, $user, $pass);
        } catch (\PDOException $e) {
            die($e->getMessage());
        }
    }

    public function table($name)
    {
        $this->table = $name;
        return $this;
    }

    public function select(...$fields)
    {
        $this->fields = implode(' , ', $fields);
        return $this;
    }

    public function skip($num = 0)
    {
        $this->limit[0] = $num;
        return $this;
    }

    public function orderBy($order)
    {
        $this->order = $order;
        return $this;
    }
    public function count(){
        return $this->select('count(*)')->first()[0];

    }

    public function add($filed_arr)
    {
        $this->filed_arr = $filed_arr;
        $this->sql_type = 'INSERT';
        return $this->execute();
    }

    public function del()
    {
        $this->sql_type = 'DELETE';
        return $this->execute();
    }

    public function update($filed_arr)
    {
        $this->filed_arr = $filed_arr;
        $this->sql_type = 'UPDATE';
        return $this->execute();
    }

    public function first()
    {
        $item = $this->get(1);
        if ($item) {
            return $item[0];
        }
        return false;
    }

    public function getAll(){
        return $this->get(-1);

    }

    /**
     * @param int $num 当num为-1时，表示取得全部数字
     *
     * @return array
     */

    public function get($num = 10)
    {
        $this->limit[1] = $num;
        $this->sql_type = 'SELECT';
        return $this->execute();
    }


    protected function execute()
    {
        $sql = '';
        switch ($this->sql_type) {

            case 'INSERT':
                $filed = implode(',', array_keys($this->filed_arr));
                $value = array_values($this->filed_arr);
                $holder = implode(
                    ',',
                    array_pad([], count($this->filed_arr), '?')
                );
                $this->sql = "INSERT INTO `{$this->table}`({$filed})VALUES({$holder})";
                $this->pdost = $this->pdo->prepare($this->sql);
                if ($this->is_debug) {
                    $this->dump($value);
                }
                $this->clear();
                return $this->pdost->execute($value);

                break;

            case 'DELETE':

                $WHERE = empty($this->condition_value)
                    ? ''
                    : ' WHERE ' . $this->condition_str;

                if ($WHERE) {
                    $this->sql = "DELETE FROM `{$this->table}` {$WHERE} ";
                    $value = $this->condition_value;
                    $this->pdost = $this->pdo->prepare($this->sql);
                    if ($this->is_debug) {
                        $this->dump($value);
                    }
                    $this->clear();
                    return $this->pdost->execute($value);
                }
                return false;

                break;

            case 'UPDATE':
                foreach ($this->filed_arr as $k => $v) {
                    $filed[] = "{$k}=?";
                }
                $filed = implode(' , ', $filed);
                $value = array_values($this->filed_arr);
                $WHERE = empty($this->condition_value)
                    ? ''
                    : ' WHERE ' . $this->condition_str;

                if ($WHERE) {
                    $this->sql = "UPDATE `{$this->table}` set {$filed} {$WHERE}";

                    $this->pdost = $this->pdo->prepare($this->sql);
                    $value = array_merge($value, $this->condition_value);
                    if ($this->is_debug) {
                        $this->dump($value);
                    }
                    $this->clear();
                    return $this->pdost->execute($value);
                }

                break;

            case 'SELECT':

                $this->fields = $this->fields ?: '*';
                $ORDER   = $this->order ? " ORDER BY {$this->order} " : '';

                $WHERE = empty($this->condition_value)
                    ? ''
                    : ' WHERE ' . $this->condition_str;
                if($this->limit[1]==-1){
                    $LIMIT='';

                }else{
                    $LIMIT = "LIMIT {$this->limit[0]},{$this->limit[1]}";
                }


                $this->sql = "SELECT {$this->fields} FROM `{$this->table}` {$WHERE} {$ORDER} {$LIMIT}";

                $this->pdost = $this->pdo->prepare($this->sql);
                $this->pdost->execute($this->condition_value);
                if ($this->is_debug) {
                    $this->dump($this->condition_value);
                }
                $this->clear();
                return $this->pdost->fetchAll();

                break;
        }
    }

    protected function clear()
    {
        $this->table = '';
        $this->fields = '';
        $this->filed_arr = [];
        $this->sql_type = '';
        $this->limit = [0, 0];
        $this->condition_value = [];
        $this->condition_str = '';
        $this->where_join = '';
        $this->is_first_where = true;
        $this->is_debug = false;
        $this->order = '';

    }


    private function _where($field, $op, $value)
    {
        $c = " `{$field}` {$op} ? ";
        $this->condition_value[] = $value;
        if ($this->is_first_where) {
            $this->condition_str .= $c;
        } else {
            $this->condition_str .= $this->where_join . $c;
        }
        $this->is_first_where = false;
        return $this;
    }

    public function where($field, $op, $value)
    {
        return $this->andWhere($field, $op, $value);
    }

    public function andWhere($field, $op, $value)
    {
        if (!$this->is_first_where) {
            $this->where_join = 'AND';
        }
        return $this->_where($field, $op, $value);
    }

    public function orWhere($field, $op, $value)
    {
        if (!$this->is_first_where) {
            $this->where_join = 'OR';
        }
        return $this->_where($field, $op, $value);
    }

    public function L()
    {
        $this->condition_str .= ' ( ';
        $this->is_first_where = true;
        return $this;
    }

    public function orL()
    {
        $this->condition_str .= ' OR ( ';
        $this->is_first_where = true;
        return $this;
    }

    public function andL()
    {
        $this->condition_str .= ' AND ( ';
        $this->is_first_where = true;
        return $this;
    }

    public function R()
    {
        $this->condition_str .= ' ) ';
        $this->is_first_where = false;
        return $this;
    }

    protected function dump($value)
    {
        if ($this->is_debug) {
            echo "SQL: {$this->sql}\n";
            echo "VALUE: \n";
            print_r($value);
            if ($this->pdost->errorInfo()[2]) {
                echo "ERROR: \n";
                print_r($this->pdost->errorInfo());
            }
        }
    }

    public function debug()
    {
        $this->is_debug = true;
        return $this;
    }


}


































